//
//  NetworkTask.m
//  MIHelloNetwork101
//
//  Created by on 13-1-21.
//  Copyright (c). All rights reserved.
//

#import "NetworkTask.h"

#define NetworkTask_TimeOutSeconds 300

@interface NetworkTask ()
@end

@implementation NetworkTask
@synthesize indentifier     =   iIndentifier;
@synthesize request         =   iRequest;
@synthesize statusCode      =   iStatusCode;
@synthesize resultData      =   iResultData;
@synthesize resultDict      =   iResultDict;

@synthesize isNeedProgress  =   _isNeedProgress;
@synthesize progress        =   _progress;
@synthesize isDictionary    =   _isDictionary;
@synthesize carInfo         =   _carInfo;

-(id)initWithGetUrl:(NSString *)url getArgs:(NSDictionary *)args{
  
    self = [super init];
    if (self) {
        if (url)
        {
            if ( args != nil )
            {
                url = [url stringByAppendingString:@"?"];
                for ( int i = 0 ; i < [[args allKeys] count] ; ++i )
                {
                    NSString *key   = [[args allKeys] objectAtIndex:i];
                    //modify by xiaolong 20130527
//                    NSString *value = [args valueForKey:key];
                    NSString *value = [NSString stringWithFormat:@"%@", [args valueForKey:key]];
                    value = (NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)value, nil, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8);
                    //end modify
                    
                    url = [url stringByAppendingFormat:@"%@=%@&", key, value];
                }
                
                url = [url substringToIndex:[url length]-1];
            }
            
            _isDictionary = YES;
            
            //delete by xiaolong 20130527
//            url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            //end delete
//            NSString* urlStr = [url stringByAddingPercentEscapesUsingEncoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000)];
//            NSLog(@"URL = %@",urlStr);
            iRequest = [[ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]] retain];
            iRequest.timeOutSeconds = NetworkTask_TimeOutSeconds;
            iRequest.cacheStoragePolicy = ASIDoNotReadFromCacheCachePolicy | ASIDoNotWriteToCacheCachePolicy;
            iRequest.delegate = self;
            iRequest.didFinishSelector = @selector(onSuccess:);
            iRequest.didFailSelector = @selector(onFail:);
            
//            NSLog(@"GET:url=%@", url);
           
        }
    }
    
    return self;
}

-(id)initWithPostUrl:(NSString *)url postArgs:(NSDictionary *)args{
    self = [super init];
    if (self) {
        if (url)
        {
            iRequest = [[ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]] retain];
            NSData* data = [NSJSONSerialization dataWithJSONObject:args options:NSJSONWritingPrettyPrinted error:nil];
            
            NSString* str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//            NSLog(@"%@\n%@", iRequest.url, str);
            SafeRelease(str);
            
            _isDictionary = YES;
            
            [iRequest appendPostData:data];
            iRequest.timeOutSeconds = NetworkTask_TimeOutSeconds;
            iRequest.cacheStoragePolicy = ASIDoNotReadFromCacheCachePolicy | ASIDoNotWriteToCacheCachePolicy;
            iRequest.delegate = self;
            iRequest.didFinishSelector = @selector(onSuccess:);
            iRequest.didFailSelector = @selector(onFail:);
        }
    }
    
    return self;
}

//upload picture
-(id)initWithPostUploadPicUrl:(NSString *)url postPicData:(NSData *)data {
    self = [super init];
    if (self) {
        if (url)
        {
            _isDictionary = YES;
            iRequest = [[ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]] retain];
            iRequest.timeOutSeconds = NetworkTask_TimeOutSeconds;
            iRequest.cacheStoragePolicy = ASIDoNotReadFromCacheCachePolicy | ASIDoNotWriteToCacheCachePolicy;
            iRequest.delegate = self;
            iRequest.didFinishSelector = @selector(onSuccess:);
            iRequest.didFailSelector = @selector(onFail:);
            
            [iRequest appendPostData:data];
        }
    }
    
    return self;
}

//sending email by Post method, that add by xiaolong in 20130815
- (id)initWithPostSendEmailUrl:(NSString*)url emailData:(NSDictionary*)paramsDic {
    if (self = [super init]) {
        _isDictionary = YES;
        
        iRequest = [[ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]] retain];
        iRequest.timeOutSeconds = NetworkTask_TimeOutSeconds;
        iRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
        iRequest.cacheStoragePolicy = ASIDoNotReadFromCacheCachePolicy | ASIDoNotWriteToCacheCachePolicy;
        iRequest.delegate = self;
        iRequest.didFinishSelector = @selector(onSuccess:);
        iRequest.didFailSelector = @selector(onFail:);
        
        //分界线的标识符
        NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
        //分界线 --AaB03x
        NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
        //结束符 AaB03x--
        NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
        
        //http body的字符串
        NSMutableString *body=[[NSMutableString alloc]init];
        //参数的集合的所有key的集合
        NSArray *keys= [paramsDic allKeys];
        
        //遍历keys
        for(int i=0;i<[keys count];i++)
        {
            //得到当前key
            NSString *key=[keys objectAtIndex:i];
            //如果key不是pic，说明value是字符类型，比如name：Boris
            if(![key isEqualToString:@"pics"])
            {
                //添加分界线，换行
                [body appendFormat:@"%@\r\n",MPboundary];
                //添加字段名称，换2行
                [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
                //添加字段的值
                [body appendFormat:@"%@\r\n",[paramsDic objectForKey:key]];
            }
        }
        
//        NSLog(@"body = %@",body);
        
        //声明myRequestData，用来放入http body
        NSMutableData *myRequestData=[NSMutableData data];
        //将body字符串转化为UTF8格式的二进制
        [myRequestData setData:[body dataUsingEncoding:NSUTF8StringEncoding]];
        
        NSDictionary* pics = [paramsDic objectForKey:@"pics"];
        
        if ([pics isKindOfClass:[NSDictionary class]]) {
            for (NSString* picKey in pics.allKeys) {
                //添加图片字段
                NSString* picBody = [NSString stringWithFormat:@"\r\n%@\r\nContent-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\nContent-Type: image/png\r\n\r\n", MPboundary, picKey, picKey];
                [myRequestData appendData:[picBody dataUsingEncoding:NSUTF8StringEncoding]];
                
//                //要上传的图片
//                UIImage* image = [pics objectForKey:picKey];
//                //得到图片的data
//                NSData *data = UIImageJPEGRepresentation(image , 0.75);
                NSData* data = [pics objectForKey:picKey];
                //将image的data加入
                [myRequestData appendData:data];
            }
        }
        
        //声明结束符：--AaB03x--
        NSString *end=[[NSString alloc]initWithFormat:@"\r\n%@",endMPboundary];
        //加入结束符--AaB03x--
        [myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
        
        //设置HTTPHeader中Content-Type的值
        NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
        //设置HTTPHeader
        [iRequest addRequestHeader:@"Content-Type" value:content];
        //设置Content-Length
//        NSLog(@"length = %@",[NSString stringWithFormat:@"%d", [myRequestData length]]);
        [iRequest addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%d", [myRequestData length]]];
        //设置http body
        [iRequest appendPostData:myRequestData];
    }
    
    return self;
}
//end add

// 断点续传
- (void)setDestFilePath:(NSString *)destFilePath tempFilePath:(NSString*)tempFilePath {
    if (destFilePath && tempFilePath) {
        iRequest.allowResumeForFileDownloads = YES;
        iRequest.downloadDestinationPath = destFilePath;
        iRequest.temporaryFileDownloadPath = tempFilePath;
        iRequest.shouldContinueWhenAppEntersBackground = YES;
    }
}

- (void)setIsNeedProgress:(BOOL)isNeedProgress
{
    _isNeedProgress = isNeedProgress;
    if ( self.isNeedProgress )
    {
        [iRequest setDownloadProgressDelegate:self];
    }
}

- (void)setCarInfo:(CarInfo *)carInfo {
    if (![_carInfo isEqual:carInfo]) {
        _carInfo = carInfo;
        
        [self setDestFilePath:_carInfo.downloadCarObj.saveFilePath tempFilePath:_carInfo.downloadCarObj.tempFilePath];
        iRequest.showAccurateProgress = YES;
        iRequest.numberOfTimesToRetryOnTimeout = 3;
        
        [NSKeyedArchiver archiveRootObject:self.carInfo.downloadCarObj toFile:self.carInfo.downloadCarObj.tempInfoPath];
    }
}

//GET
- (void)onSuccess:(ASIHTTPRequest*)request{
//    NSLog(@"[%@][onSuccess], http code:%d", self, request.responseStatusCode);
    iStatusCode = request.responseStatusCode;
    if (2 == iStatusCode / 100) {
//        NSLog(@"[%@][onSuccess], http code:%d", self, request.responseStatusCode);
        iResultData = [request.responseData retain];
        NSString* str = [[NSString alloc] initWithData:iResultData encoding:NSUTF8StringEncoding];
//        NSLog(@"Response:\n%@",str);
        SafeRelease(str);
        if (_isDictionary) {
            NSError * error = nil;
            iResultDict = [NSJSONSerialization JSONObjectWithData:iResultData options:NSJSONReadingAllowFragments error:&error];
            if (nil != error && [error isKindOfClass:[NSError class]]) {
//                NSLog(@"%@  @@%s", error, __func__);
            }
//            NSLog(@"解析Dictionary成功,结果为:\n%@",iResultDict);
        } else if (nil != self.carInfo) { //add by xiaolong 20130514
            
            self.carInfo.downloadCarObj.state = Finish_State;
            self.carInfo.downloadCarObj.progress = 1;
            [NSKeyedArchiver archiveRootObject:self.carInfo.downloadCarObj toFile:self.carInfo.downloadCarObj.tempInfoPath];
            
        }
        //方式一：通知调用子类方法
        [self onSuccessBySub];
        //方式二：直接通知业务类，携带task参数
        [[NSNotificationCenter defaultCenter] postNotificationName:NetworkTask_NotificationName_OnSuccess object:self];
        
//        NSLog(@"%@", iResultDict);
    }
    else{
        [self onFail:request];
    }
}

//
- (void)onFail:(ASIHTTPRequest*)request{
//    NSLog(@"[%@][onFail], http code:%d", self, request.responseStatusCode);
    iStatusCode = request.responseStatusCode;
    iResultData = [request.responseData retain];
    NSString* str = [[NSString alloc] initWithData:iResultData encoding:NSUTF8StringEncoding];
//    NSLog(@"Response:\n%@",str);
    SafeRelease(str);
//    if (nil != self.carInfo) {
//        self.carInfo.downloadCarObj.state = DownloadError_State;
//        [NSKeyedArchiver archiveRootObject:self.carInfo.downloadCarObj toFile:self.carInfo.downloadCarObj.tempInfoPath];
//    }
    
    [self onFailBySub];
    [[NSNotificationCenter defaultCenter] postNotificationName:NetworkTask_NotificationName_OnFail object:self];
}

- (void)onFinishReq:(ASIFormDataRequest *)request
{
}

- (void)onFailReq:(ASIFormDataRequest *)request
{
}

- (BOOL)onSuccessBySub
{
    return YES;
}

- (BOOL)onFailBySub
{
    return YES;
}

#pragma mark-protocol :<ASIProgressDelegate>
- (void)setProgress:(float)newProgress{
    _progress = newProgress;
//    NSLog(@"_progress:%f", _progress);
    
    if (nil != self.carInfo) {
        self.carInfo.downloadCarObj.progress = _progress;
        [NSKeyedArchiver archiveRootObject:self.carInfo.downloadCarObj toFile:self.carInfo.downloadCarObj.tempInfoPath];
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:NetworkTask_NotificationName_OnProgress object:self];
}

- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders{
    if (nil == self.carInfo) {
        return;
    }
    
    //2xx表示请求正确响应，其它为异常响应
    if([request responseStatusCode]<200||[request responseStatusCode]>=300){
        return;
    }
    
    if (![self.carInfo.downloadCarObj.eTag isEqualToString:[responseHeaders objectForKey:@"Etag"]]) {
        self.carInfo.downloadCarObj.progress = 0.0;
        
        if (![self.carInfo.downloadCarObj.eTag isEqualToString:@"eTag"]) {
            self.carInfo.downloadCarObj.state = DownloadError_State;
            [iRequest clearDelegatesAndCancel];
            [iRequest release];
        }
        
        self.carInfo.downloadCarObj.eTag = [responseHeaders objectForKey:@"Etag"];
        [NSKeyedArchiver archiveRootObject:self.carInfo.downloadCarObj toFile:self.carInfo.downloadCarObj.tempInfoPath];
        [[NSFileManager defaultManager] removeItemAtPath:self.carInfo.downloadCarObj.tempFilePath error:nil];
        
        return;
    }
    
    BOOL isDir;
    if (!([[NSFileManager defaultManager] fileExistsAtPath:self.carInfo.downloadCarObj.tempFilePath isDirectory:&isDir] && !isDir))
    {
        if (!([[NSFileManager defaultManager] fileExistsAtPath:self.carInfo.downloadCarObj.tempCarPath isDirectory:&isDir] && isDir)) {
            NSError * error = nil;
            [[NSFileManager defaultManager] createDirectoryAtPath:self.carInfo.downloadCarObj.tempCarPath
                                      withIntermediateDirectories:YES
                                                       attributes:nil
                                                            error:&error];
            
        }
        [[NSFileManager defaultManager] createFileAtPath:self.carInfo.downloadCarObj.tempFilePath contents:[NSData data] attributes:nil];
        self.carInfo.downloadCarObj.eTag = [responseHeaders objectForKey:@"Etag"];
        [NSKeyedArchiver archiveRootObject:self.carInfo.downloadCarObj toFile:self.carInfo.downloadCarObj.tempInfoPath];
    }
}

//
- (void)dealloc{
    self.indentifier = nil;
    if (iRequest) {
        iRequest.delegate = nil;
        [iRequest cancel];
        [iRequest release];
    }
    if (iResultData) {
        [iResultData release];
    }
    
    [super dealloc];
}

@end
